package io.netty.groupchat;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;
import lombok.extern.slf4j.Slf4j;

/**
 * 群聊服务端处理
 *
 * @author Verlet
 * @date 2023-02-04 23:54
 */
@Slf4j
public class GroupChatServerHandler extends SimpleChannelInboundHandler<String> {

    private static final ChannelGroup CHANNEL_GROUP = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    /**
     * 创建连接建立执行，第一个被执行
     */
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        log.info("handlerAdded");
        Channel channel = ctx.channel();
        CHANNEL_GROUP.add(channel);
        CHANNEL_GROUP.writeAndFlush("用户 [ " + channel.remoteAddress() + " ] 加入群聊,当前在线人数为 " + CHANNEL_GROUP.size());
    }

    /**
     * 断开连接
     */
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        log.info("handlerRemoved");
        Channel channel = ctx.channel();
        CHANNEL_GROUP.writeAndFlush("用户 [ " + channel.remoteAddress() + " ] 退出群聊,当前在线人数为 " + CHANNEL_GROUP.size());
    }

    /**
     * channel 处于活跃状态
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.info("channelActive");
        log.info("{} 上线了~", ctx.channel().remoteAddress());
    }

    /**
     * channel 处于不活跃状态
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.info("channelInactive");
        log.info("{} 下线了~", ctx.channel().remoteAddress());
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.error(cause.getMessage());
        Channel channel = ctx.channel();
        CHANNEL_GROUP.remove(channel);
        channel.close();
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
        String hostname = null;
        // 实现单聊功能 @hostname msg
        if (msg.startsWith("@")) {
            hostname = msg.substring(1, msg.indexOf(" "));
            msg = msg.substring(msg.indexOf(" ") + 1);
        }

        Channel channel = ctx.channel();
        msg =  channel.remoteAddress() + " ==> " + msg;
        for (Channel ch : CHANNEL_GROUP){
            if(ch != channel){
                // 单聊功能，目标channel不是当前channel
                if (hostname != null && !hostname.equals(ch.remoteAddress().toString().substring(1))) {
                    continue;
                }
                log.info("服务端转发 {}",  msg);
                ch.writeAndFlush(msg);
            }

        }
    }

}
